package com.ticket.sass.provider.interceptor;


import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.ticket.sass.common.exception.enums.ErrorCode;
import com.ticket.sass.common.exception.exception.UnauthorizedException;
import com.ticket.sass.provider.annotation.AuthIgnore;
import com.ticket.sass.provider.util.JwtUtil;
import com.ticket.sass.provider.util.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.helper.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author ywb
 * @date 2023-05-24 16:17
 */
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AuthenticationInterceptor implements HandlerInterceptor {
    @Autowired
    private JwtUtil jwtUtil;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        log.info("====================进入请求过滤器链============================");
        log.info(
            "请求方法类型【{}】, 请求IP【{}】，访问路径【{}】",
            request.getMethod(),
            ResponseUtil.getRemoteHost(request),
            request.getRequestURI()
        );
        
        // 不属于方法放过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        
        HandlerMethod method = (HandlerMethod) handler;
        
        // 放行
        AuthIgnore authIgnore = method.getMethodAnnotation(AuthIgnore.class);
        if (authIgnore != null) {
            // 获取注解的 reason 属性值
            String reason = authIgnore.reason();
            // 输出日志
            log.info("放行原因: {}", StringUtil.isBlank(reason) ? "使用了AuthIgnore注解" : reason);
            return true;
        }

        // 获取 TOKEN
        String authToken = jwtUtil.getAuthToken(request);

        // 未携带 token 拦截下来
        if (StrUtil.isBlank(authToken)) {
            throw new UnauthorizedException(
                ErrorCode.UNAUTHORIZED,
                ErrorCode.UNAUTHORIZED.getReasonPhrase()
            );
        }
        
        try {
            jwtUtil.verify(authToken).map(decodedJWT -> {
                String aud = decodedJWT.getClaims().get("aud").asString();
                if (aud == null) {
                    throw new UnauthorizedException(ErrorCode.UNAUTHORIZED, ErrorCode.UNAUTHORIZED.getReasonPhrase());
                }
                Long id = Long.valueOf(aud);
                
//                if (Objects.isNull(admin)){
//                    log.info("token校验通过，但未通过登录接口发行，伪造token 即将被捕获");
//                    throw new UnauthorizedException(
//                        ErrorCode.UNAUTHORIZED,
//                        ErrorCode.UNAUTHORIZED.getReasonPhrase()
//                    );
//                }
//                if (!admin.getEnable()){
//                    throw new UnauthorizedException(
//                        ErrorCode.UNAUTHORIZED,
//                        "账户已禁用"
//                    );
//                }

                
//                redisCache.setKeyExpireTime(jwtUtil.validTokenCacheKey(id), 2, TimeUnit.DAYS);
                response.setHeader("Authorization", jwtUtil.createToken(id, "").getToken());
                response.setHeader("Access-Control-Expose-Headers","Authorization");
                
                return true;
            }).orElseThrow(() -> new UnauthorizedException(ErrorCode.UNAUTHORIZED, ErrorCode.UNAUTHORIZED.getReasonPhrase()));
        } catch (JWTDecodeException exception) {
            throw new UnauthorizedException(ErrorCode.UNAUTHORIZED, ErrorCode.UNAUTHORIZED.getReasonPhrase());
        }
        return true;
    }
}
